5.11. Иерархия исключений в Ruby
Иерархия исключений в Ruby
Корневой класс:
Exception
Основные подклассы Exception:
-
SystemExit— вызывается при завершении программы (exit,Kernel#exit). -
SignalException— получение сигнала ОС (например,SIGINTпри нажатии Ctrl+C).Interrupt— частный случайSignalExceptionдляSIGINT.
-
ScriptError— ошибки синтаксиса и загрузки:LoadErrorNotImplementedErrorSyntaxError
-
StandardError— основной родитель для большинства исключений, возникающих в пользовательском коде.ArgumentErrorUncaughtThrowError
EncodingErrorCompatibilityError
FiberErrorIOErrorEOFError
IndexErrorKeyErrorStopIteration
LocalJumpErrorNameErrorNoMethodError
RangeErrorFloatDomainError
RegexpErrorRuntimeErrorSecurityErrorSystemCallError— базовый класс для системных ошибок (аналогErrno::*).- Подклассы создаются динамически:
Errno::ENOENT,Errno::EACCES,Errno::EEXISTи т.д.
- Подклассы создаются динамически:
ThreadErrorTypeErrorZeroDivisionError
-
fatal— внутренний псевдокласс (на самом деле не используется напрямую); некоторые фатальные ошибки VM могут быть представлены какfatal, но они не перехватываются обычнымrescue.
Особенности:
-
rescueбез аргументов перехватывает толькоStandardErrorи его подклассы.
Пример:begin
# ...
rescue => e
# то же, что rescue StandardError => e
end -
Чтобы перехватить все исключения (включая
SystemExit,SignalException), нужно явно указатьException:begin
# ...
rescue Exception => e
# крайне не рекомендуется в production
end -
Системные ошибки (
Errno::*) генерируются автоматически при ошибках системных вызовов (например, открытие несуществующего файла →Errno::ENOENT). -
NoMethodError— одна из самых частых ошибок: вызов несуществующего метода. -
KeyError— выбрасывается при использованииHash#fetchс отсутствующим ключом без значения по умолчанию. -
StopIteration— используется для завершения итераторов (внутренне вEnumerator).
Как получить список программно:
Ruby позволяет инспектировать иерархию классов:
# Все подклассы Exception
def subclasses_of(klass)
klass.subclasses + klass.subclasses.flat_map { |k| subclasses_of(k) }
end
puts subclasses_of(Exception).map(&:name).sort
Примечание: метод
subclassesдоступен только в режиме отладки или при подключении соответствующих утилит; в общем случае можно использоватьObjectSpace.each_object(Class).
Рекомендации:
- Для пользовательских исключений создавайте подклассы
StandardError:class MyCustomError < StandardError; end - Не перехватывайте
Exceptionбез веской причины — это может помешать корректному завершению программы (например, игнорированиюCtrl+C).